#pragma once
#include "hHashVectorIterator.h"

namespace hHashVectorDetail
{
	template <typename Val, bool IsConst>
	auto Iterator<Val, IsConst>::operator->()->std::shared_ptr<RetPr>
	{
		assert(_ppNode);
		assert(*_ppNode);
		assert((*_ppNode)->_val);
		return std::make_shared<RetPr>(std::piecewise_construct, std::tuple<size_t>((*_ppNode)->_key), std::tuple<ValRef>(*(*_ppNode)->_val));
	}

	template <typename Val, bool IsConst>
	auto Iterator<Val, IsConst>::operator->() const->std::shared_ptr<CRetPr>
	{
		assert(_ppNode);
		assert(*_ppNode);
		assert((*_ppNode)->_val);
		return std::make_shared<CRetPr>(std::piecewise_construct, std::tuple<size_t>((*_ppNode)->_key), std::tuple<CValRef>(*(*_ppNode)->_val));
	}

	template <typename Val, bool IsConst>
	auto Iterator<Val, IsConst>::operator*()->typename Iterator<Val, IsConst>::RetPr
	{
		assert(_ppNode);
		assert(*_ppNode);
		assert((*_ppNode)->_val);
		return std::make_pair((*_ppNode)->_key, ValRef(*(*_ppNode)->_val));
	}

	template <typename Val, bool IsConst>
	auto Iterator<Val, IsConst>::operator++()->Iterator<Val, IsConst>&
	{
		assert(_ppNode);
		assert(*_ppNode);
		assert((*_ppNode)->_val);
		operator=((*_ppNode)->getNext());
		return *this;
	}

	template <typename Val, bool IsConst>
	auto Iterator<Val, IsConst>::operator++(int)->Iterator<Val, IsConst>
	{
		assert(_ppNode);
		assert(*_ppNode);
		assert((*_ppNode)->_val);
		auto it = *this;
		operator=((*_ppNode)->getNext());
		return it;
	}

	template <typename Val, bool IsConst>
	bool Iterator<Val, IsConst>::operator==(const Iterator<Val, IsConst>& other) const
	{
		if (operator bool() ^ other)
			return false;

		if (!other)
			return true;

		return *_ppNode == *other._ppNode;
	}

	template <typename Val, bool IsConst>
	Iterator<Val, IsConst>::operator bool() const
	{
		if (!_ppNode)
			return false;

		auto pNode = *_ppNode;
		if (!pNode)
			return false;

		if (!pNode->_ppOwner)
			return false;

		return true;
	}

}